package services.impl;

import services.*;
import entities.*;
import java.util.List;
import java.util.LinkedList;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.function.Predicate;
import java.util.Arrays;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BooleanSupplier;
import org.apache.commons.lang3.SerializationUtils;
import java.util.Iterator;

public class JoinTeamServiceImpl implements JoinTeamService, Serializable {
	
	
	public static Map<String, List<String>> opINVRelatedEntity = new HashMap<String, List<String>>();
	
	
	ThirdPartyServices services;
			
	public JoinTeamServiceImpl() {
		services = new ThirdPartyServicesImpl();
	}

	
	//Shared variable from system services
	
	/* Shared variable from system services and get()/set() methods */
			
	/* all get and set functions for temp property*/
				
	
	
	/* Generate inject for sharing temp variables between use cases in system service */
	public void refresh() {
		LabManageSystem labmanagesystem_service = (LabManageSystem) ServiceManager.getAllInstancesOf("LabManageSystem").get(0);
	}
	
	/* Generate buiness logic according to functional requirement */
	@SuppressWarnings("unchecked")
	public boolean applyJoinTeam(String teamId, String studentId) throws PreconditionException, PostconditionException, ThirdPartyServiceException {
		
		
		/* Code generated for contract definition */
		//Get team
		Team team = null;
		//no nested iterator --  iterator: any previous:any
		for (Team t : (List<Team>)EntityManager.getAllInstancesOf("Team"))
		{
			if (t.getId().equals(teamId))
			{
				team = t;
				break;
			}
				
			
		}
		//Get stu
		Student stu = null;
		//no nested iterator --  iterator: any previous:any
		for (Student s : (List<Student>)EntityManager.getAllInstancesOf("Student"))
		{
			if (s.getId().equals(studentId))
			{
				stu = s;
				break;
			}
				
			
		}
		//Get apply
		Apply apply = null;
		//no nested iterator --  iterator: any previous:any
		for (Apply a : (List<Apply>)EntityManager.getAllInstancesOf("Apply"))
		{
			if (a.getAimId().equals(teamId) && a.getBelongStudent().equals(studentId) && a.getApplyType() == ApplyType.JOINTEAM)
			{
				apply = a;
				break;
			}
				
			
		}
		/* previous state in post-condition*/
 
		/* check precondition */
		if (StandardOPs.oclIsundefined(team) == false && StandardOPs.oclIsundefined(stu) == false && StandardOPs.oclIsundefined(apply) == true) 
		{ 
			/* Logic here */
			Apply a = null;
			a = (Apply) EntityManager.createObject("Apply");
			a.setAimId(teamId);
			a.setBelongStudent(studentId);
			a.setApplyType(ApplyType.JOINTEAM);
			
			
			refresh();
			// post-condition checking
			if (!(true && 
			a.getAimId() == teamId
			 && 
			a.getBelongStudent() == studentId
			 && 
			a.getApplyType() == ApplyType.JOINTEAM
			 && 
			true)) {
				throw new PostconditionException();
			}
			
		
			//return primitive type
			refresh();				
			return true;
		}
		else
		{
			throw new PreconditionException();
		}
		//string parameters: [teamId, studentId] 
		//all relevant vars : a
		//all relevant entities : Apply
	}  
	
	static {opINVRelatedEntity.put("applyJoinTeam", Arrays.asList("Apply"));}
	 
	@SuppressWarnings("unchecked")
	public boolean applyJoinGroup(String groupId, String studentId) throws PreconditionException, PostconditionException, ThirdPartyServiceException {
		
		
		/* Code generated for contract definition */
		//Get group
		Group group = null;
		//no nested iterator --  iterator: any previous:any
		for (Group g : (List<Group>)EntityManager.getAllInstancesOf("Group"))
		{
			if (g.getId().equals(groupId))
			{
				group = g;
				break;
			}
				
			
		}
		//Get stu
		Student stu = null;
		//no nested iterator --  iterator: any previous:any
		for (Student s : (List<Student>)EntityManager.getAllInstancesOf("Student"))
		{
			if (s.getId().equals(studentId))
			{
				stu = s;
				break;
			}
				
			
		}
		//Get apply
		Apply apply = null;
		//no nested iterator --  iterator: any previous:any
		for (Apply a : (List<Apply>)EntityManager.getAllInstancesOf("Apply"))
		{
			if (a.getAimId().equals(groupId) && a.getBelongStudent().equals(studentId) && a.getApplyType() == ApplyType.JOINGROUP)
			{
				apply = a;
				break;
			}
				
			
		}
		//Get team
		Team team = null;
		//no nested iterator --  iterator: any previous:any
		for (Team t : (List<Team>)EntityManager.getAllInstancesOf("Team"))
		{
			if (StandardOPs.oclIsundefined(group) == false && t.getId() == group.getBelongTeam())
			{
				team = t;
				break;
			}
				
			
		}
		/* previous state in post-condition*/
 
		/* check precondition */
		if (StandardOPs.oclIsundefined(group) == false && StandardOPs.oclIsundefined(team) == false && StandardOPs.oclIsundefined(stu) == false && StandardOPs.oclIsundefined(apply) == true && StandardOPs.oclIsundefined(team) == false) 
		{ 
			/* Logic here */
			Apply a = null;
			a = (Apply) EntityManager.createObject("Apply");
			a.setAimId(groupId);
			a.setBelongStudent(studentId);
			a.setApplyType(ApplyType.JOINGROUP);
			
			
			refresh();
			// post-condition checking
			if (!(true && 
			a.getAimId() == groupId
			 && 
			a.getBelongStudent() == studentId
			 && 
			a.getApplyType() == ApplyType.JOINGROUP
			 && 
			true)) {
				throw new PostconditionException();
			}
			
		
			//return primitive type
			refresh();				
			return true;
		}
		else
		{
			throw new PreconditionException();
		}
		//string parameters: [groupId, studentId] 
		//all relevant vars : a
		//all relevant entities : Apply
	}  
	
	static {opINVRelatedEntity.put("applyJoinGroup", Arrays.asList("Apply"));}
	 
	@SuppressWarnings("unchecked")
	public boolean exitGroup(String groupId, String studentId) throws PreconditionException, PostconditionException, ThirdPartyServiceException {
		
		
		/* Code generated for contract definition */
		//Get sig
		StudentInGroup sig = null;
		//no nested iterator --  iterator: any previous:any
		for (StudentInGroup s : (List<StudentInGroup>)EntityManager.getAllInstancesOf("StudentInGroup"))
		{
			if (s.getGroupId().equals(groupId) && s.getStudentId().equals(studentId))
			{
				sig = s;
				break;
			}
				
			
		}
		/* previous state in post-condition*/
 
		/* check precondition */
		if (StandardOPs.oclIsundefined(sig) == false) 
		{ 
			/* Logic here */
			EntityManager.deleteObject("StudentInGroup", sig);
			
			
			refresh();
			// post-condition checking
			if (!(StandardOPs.excludes(((List<StudentInGroup>)EntityManager.getAllInstancesOf("StudentInGroup")), sig)
			 && 
			true)) {
				throw new PostconditionException();
			}
			
		
			//return primitive type
			refresh();				
			return true;
		}
		else
		{
			throw new PreconditionException();
		}
		//string parameters: [groupId, studentId] 
		//all relevant vars : sig
		//all relevant entities : StudentInGroup
	}  
	
	static {opINVRelatedEntity.put("exitGroup", Arrays.asList("StudentInGroup"));}
	 
	@SuppressWarnings("unchecked")
	public boolean exitTeam(String teamId, String studentId) throws PreconditionException, PostconditionException, ThirdPartyServiceException {
		
		
		/* Code generated for contract definition */
		//Get sit
		StudentInTeam sit = null;
		//no nested iterator --  iterator: any previous:any
		for (StudentInTeam s : (List<StudentInTeam>)EntityManager.getAllInstancesOf("StudentInTeam"))
		{
			if (s.getTeamId().equals(teamId) && s.getStudentId().equals(studentId))
			{
				sit = s;
				break;
			}
				
			
		}
		//Get sigs
		List<StudentInGroup> sigs = new LinkedList<>();
		//no nested iterator --  iterator: select previous:select
		for (StudentInGroup s : (List<StudentInGroup>)EntityManager.getAllInstancesOf("StudentInGroup"))
		{
			if (s.getStudentId().equals(studentId))
			{
				sigs.add(s);
			}
				
			
		}
		//Get gs
		List<Group> gs = new LinkedList<>();
		//no nested iterator --  iterator: select previous:select
		for (Group g : (List<Group>)EntityManager.getAllInstancesOf("Group"))
		{
			if (g.getBelongTeam().equals(teamId))
			{
				gs.add(g);
			}
				
			
		}
		//Get git
		Group git = null;
		//has nested iterator	
		for (StudentInGroup s : sigs)
		{
			//nested for here:
			//no nested iterator --  iterator: exists previous:any
			for (Group g : gs)
			{
				if (g.getId() == s.getGroupId())
				{
					git = g;
					break;
				}
					
				
			}
		}
		/* previous state in post-condition*/
 
		/* check precondition */
		if (StandardOPs.oclIsundefined(sit) == false && StandardOPs.oclIsundefined(git) == false) 
		{ 
			/* Logic here */
			EntityManager.deleteObject("StudentInTeam", sit);
			
			
			refresh();
			// post-condition checking
			if (!(StandardOPs.excludes(((List<StudentInTeam>)EntityManager.getAllInstancesOf("StudentInTeam")), sit)
			 && 
			true)) {
				throw new PostconditionException();
			}
			
		
			//return primitive type
			refresh();				
			return true;
		}
		else
		{
			throw new PreconditionException();
		}
		//string parameters: [teamId, studentId] 
		//all relevant vars : sit
		//all relevant entities : StudentInTeam
	}  
	
	static {opINVRelatedEntity.put("exitTeam", Arrays.asList("StudentInTeam"));}
	 
	
	
	
	/* temp property for controller */
			
	/* all get and set functions for temp property*/
	
	/* invarints checking*/
	public final static ArrayList<String> allInvariantCheckingFunction = new ArrayList<String>(Arrays.asList());
			
}
